package com.ruoyi.system.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.constant.UserConstants;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.TranslationUtil;
import com.ruoyi.common.core.utils.bean.BeanUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.params.SysPostParams;
import com.ruoyi.system.exception.SystemException;
import com.ruoyi.system.mapper.SysPostMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysLanguageDataService;
import com.ruoyi.system.service.ISysPostService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 岗位信息 服务层处理
 *
 * @author ruoyi
 */
@Service
@Slf4j
public class SysPostServiceImpl implements ISysPostService {
    @Autowired
    private SysPostMapper postMapper;

    @Autowired
    private ISysDeptService sysDeptService;

    @Autowired
    private SysUserMapper userMapper;
    @Autowired
    private ISysLanguageDataService sysLanguageDataService;

    /**
     * 查询岗位信息集合
     *
     * @param post 岗位信息
     * @return 岗位信息集合
     */
    @Override
    public Page<SysPost> selectPostList(Page<SysPost> page,SysPostParams post) {
        Long deptId = post.getDeptId();
        List<Long> deptIds = sysDeptService.selectDeptAncestors(deptId);
        deptIds.add(deptId);
        post.setDeptIds(deptIds);
        post.setDeptId(null);
        Page<SysPost> sysPostPage = postMapper.selectPostList(page,post);
        List<SysPost> sysPostOldList = sysPostPage.getRecords();
        List<SysPost> sysPostList = new ArrayList<>();
        Map<String, SysPost> sysPostOldMap = new HashMap<>();
        for (SysPost sysPost : sysPostOldList) {
            //需要添加删除状态作为唯一标识 否则可能会拿到删除的数据  后设计数据只有一条 如果存在删除的就激活
            sysPostOldMap.put(sysPost.getDeptId() + "_" + sysPost.getPostCode(), sysPost);
        }
        Map<String, SysPost> sysPostNewMap = new HashMap<>();
        for (SysPost sysPost : sysPostOldList) {
            if (sysPostNewMap.get(sysPost.getPostCode()) == null) {
                SysPost sysPostNew = null;
                SysPost sysPostTopFloor = null;
                for (Long deptIdTemp : deptIds) {
                    SysPost sysPostTemp = sysPostOldMap.get(deptIdTemp + "_" + sysPost.getPostCode());
                    //当存在的时候
                    if (sysPostTemp != null) {
                        //当删除的时候 不显示
                        /*if(sysPostTemp.getDelFlag().equals("2") && deptIdTemp.equals(deptId)){
                            sysPostNew = null;
                        }else if(sysPostTemp.getDelFlag().equals("0") &&
                                (sysPostTemp.getIsAllowExtends().equals("Y") || deptIdTemp.equals(deptId))) {

                            if (sysPostNew == null) {
                                sysPostNew = new SysPost();
                                BeanUtils.copyPropertiesIgnoreNull(sysPostTemp, sysPostNew);
                                sysPostTopFloor = sysPostTemp;
                            } else {
                                log.info("------------------PostId-------------------:" + sysPostTemp.getPostId());
                                BeanUtils.copyPropertiesIgnoreNull(sysPostTemp, sysPostNew);
                            }
                        }*/
                        if (sysPostTemp.getIsAllowExtends().equals("Y") || deptIdTemp.equals(deptId)) {
                            if (sysPostTemp.getDelFlag().equals("0")) {
                                if (sysPostTopFloor == null) {
                                    sysPostTopFloor = sysPostTemp;
                                }
                            }
                            if (sysPostNew == null) {
                                sysPostNew = new SysPost();
                            }
                            //当为删除了的时候只继承删除 其他不继承
                            if (sysPostTemp.getDelFlag().equals("2")) {
                                sysPostNew.setDelFlag("2");
                            } else {
                                BeanUtils.copyPropertiesIgnoreNull(sysPostTemp, sysPostNew);
                            }

                        }
                    }


                }
 /*               if (sysPostNew != null) {
                    //当顶层的部门号与当前部门号相同的时候证明是顶层
                    if(sysPostTopFloor.getDeptId().equals(deptId)){
                        sysPostNew.setIsTopFloor("Y");
                    }else{
                        sysPostNew.setIsTopFloor("N");
                    }
                    sysPostList.add(sysPostNew);
                    sysPostNewMap.put(sysPostNew.getPostCode(), sysPostNew);
                }*/

                if (sysPostNew != null && !sysPostNew.getDelFlag().equals("2")) {
                    //当顶层的部门号与当前部门号相同的时候证明是顶层
                    if (sysPostTopFloor.getDeptId().equals(deptId)) {
                        sysPostNew.setIsTopFloor("Y");
                    } else {
                        sysPostNew.setIsTopFloor("N");
                    }
                    sysPostList.add(sysPostNew);
                    sysPostNewMap.put(sysPostNew.getPostCode(), sysPostNew);
                }
            }
        }
        Collections.sort(sysPostList, new Comparator<SysPost>() {
            @Override
            public int compare(SysPost o1, SysPost o2) {
                Integer sort1 = o1.getPostSort() == null ? 0 : o1.getPostSort();
                Integer sort2 = o2.getPostSort() == null ? 0 : o2.getPostSort();
                return sort1 > sort2 ? 1 : sort1.equals(sort2) ? 0 : -1;
            }
        });
        sysPostList.forEach(p -> {
            SysLanguageData languageData = sysLanguageDataService.selectByRef(p.getPostId(), "post");
            if (languageData != null) {
                TranslationUtil.translation(languageData.getValue(),p);
            }
        });
        sysPostPage.setRecords(sysPostList);
        return sysPostPage;
    }

    @Override
    public List<SysPost> selectPostByDeptId(Long deptId) {
        SysPostParams sysPostParams = new SysPostParams();
        sysPostParams.setDeptId(deptId);
        Page<SysPost> page = new Page<>(1, -1);
        return this.selectPostList(page,sysPostParams).getRecords();
    }

    /**
     * 查询所有岗位
     *
     * @return 岗位列表
     */
//    @Override
//    public List<SysPost> selectPostAll()
//    {
//        return this.selectPostList(new SysPostParams());
//    }


    /**
     * 通过岗位ID查询岗位信息
     *
     * @param postId 岗位ID
     * @return 岗位对象信息
     */
    @Override
    public SysPost selectPostById(Long postId) {

        SysPost sysPost = postMapper.selectPostById(postId);
        SysPost sysPostNew = selectPost(sysPost.getDeptId(), sysPost.getPostCode());
        sysPost = sysPostNew != null ? sysPostNew : sysPost;
        return sysPost;
    }

    @Override
    public SysPost selectPost(Long deptId, String postCode) {
        SysPost sysPost = null;
        SysPostParams sysPostParams = new SysPostParams();
        sysPostParams.setPostCode(postCode);
        sysPostParams.setDeptId(deptId);
        Page<SysPost> page = new Page<>(1, -1);
        List<SysPost> selectPostList = this.selectPostList(page,sysPostParams).getRecords();
        if (selectPostList.size() > 0) {
            sysPost = selectPostList.get(0);
        }

        return sysPost;
    }

    /**
     * 通过岗位CODE查询岗位信息
     *
     * @param postCode 岗位CODE
     * @return 岗位对象信息
     */
//    @Override
//    public SysPost selectPostByCode(String postCode)
//    {
//        return postMapper.selectPostByCode(postCode);
//    }

    /**
     * 根据用户ID获取岗位选择框列表
     *
     * @param userId 用户ID
     * @return 选中岗位ID列表
     */
    @Override
    public List<SysPost> selectPostListByUserId(Long userId) {
        SysUser sysUser = userMapper.selectUserById(userId);
        return this.selectPostListByUser(sysUser);
    }

    @Override
    public List<SysPost> selectPostListByUser(SysUser sysUser) {
        if (sysUser == null) {
            return null;
        }
        SysPostParams sysPostParams = new SysPostParams();
        sysPostParams.setDeptId(sysUser.getDeptId());
        sysPostParams.setUserId(sysUser.getUserId());
        Page<SysPost> page = new Page<>(1, -1);
        List<SysPost> sysPostList = this.selectPostList(page,sysPostParams).getRecords();
        return sysPostList;
    }

    /**
     * 校验岗位名称是否唯一
     *
     * @return 结果
     */
    @Override
    public String checkPostNameUnique(Long postId, Long deptId, String postName) {
        postId = StringUtils.isNull(postId) ? -1L : postId;
        SysPost info = postMapper.checkPostNameUnique(deptId, postName);
        if (StringUtils.isNotNull(info) && info.getPostId().longValue() != postId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 校验岗位编码是否唯一
     *
     * @return 结果
     */
    @Override
    public String checkPostCodeUnique(Long postId, Long deptId, String postCode) {
        postId = StringUtils.isNull(postId) ? -1L : postId;
        SysPost info = postMapper.checkPostCodeUnique(deptId, postCode);
        if (StringUtils.isNotNull(info) && info.getPostId().longValue() != postId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 通过岗位ID查询岗位使用数量
     *
     * @return 结果
     */
//    @Override
//    public int countUserPostById(Long postId)
//    {
//        return userPostMapper.countUserPostById(postId);
//    }


    //检查是否有继承  获取继承  前提条件是允许继承
    public List<SysPost> getExtendPosts(Long deptId, String postCode) {
        SysPostParams sysPostParams = new SysPostParams();
        sysPostParams.setPostCode(postCode);
        sysPostParams.setDeptId(deptId);
        sysPostParams.setStatus("");
        Page<SysPost> page = new Page<>(1, -1);
        List<SysPost> sysPostList = postMapper.selectPostList(page,sysPostParams).getRecords();
        for (int i = 0; i < sysPostList.size(); i++) {
            SysPost sysPost = sysPostList.get(i);
            if (sysPost.getDeptId().equals(deptId)) {
                sysPostList.remove(i);
                i--;
            }
        }
        return sysPostList;
    }

    /**
     * 删除岗位信息
     *
     * @param sysPostKey
     * @return 结果
     */
    @Override
    @Transactional
    public int deletePost(SysPostUnique sysPostKey) {

        //判断是否为顶层 如果为顶层并且存在继承不允许删除
        SysPost postOld = this.selectPost(sysPostKey.getDeptId(), sysPostKey.getPostCode());

        //获取原始的数据
        SysPost sysPostOrigin = postMapper.selectPostByDeptAndCodeOrg(sysPostKey.getDeptId(), sysPostKey.getPostCode());

        //判断是否为顶层
        if (postOld.getIsTopFloor().equals("Y")) {
            if (postOld.getIsAllowExtends().equals("Y")) {//当是允许继承的岗位
                if (getExtendPosts(postOld.getDeptId(), postOld.getPostCode()).size() > 0) {
                    throw new SystemException(SystemException.NOT_ALLOW_DELETE).setBusinessMessage("该岗位存在继承，不允许修改");
                }
            }
        }

        //通过deptId和postKey判断是否使用 如果使用了不允许删除 待优化
    /*     if (countUserPostByPostId(postId) > 0) {
            throw new CustomException(String.format("%1$s已分配,不能删除", post.getPostName()));
        }*/
        int successNum = 0;
        //当数据已经存在的时候
        if (sysPostOrigin != null) {
            SysPost postUpdate = new SysPost();
            postUpdate.setPostId(sysPostOrigin.getPostId());
            postUpdate.setDelFlag("2");
            postUpdate.setUpdateTime(DateUtils.getNowDate());
            postUpdate.setUpdateBy(SecurityUtils.getUsername());
            successNum = postMapper.updatePost(postUpdate);
        } else {
            //当数据不存在的时候
            SysPost postInsert = new SysPost();
            postInsert.setDelFlag("2");
            postInsert.setDeptId(sysPostKey.getDeptId());
            postInsert.setPostCode(sysPostKey.getPostCode());
            postInsert.setIsAllowExtends("Y");
            successNum = postMapper.insertPost(postInsert);

        }

        return successNum;
    }

    /**
     * 批量删除岗位信息
     *
     * @param sysPostCodeList 需要删除的岗位唯一键集合
     * @return 结果
     * @throws Exception 异常
     */
    @Override
    @Transactional
    public int deletePostByCodes(List<SysPostUnique> sysPostCodeList) {
        if (sysPostCodeList == null || sysPostCodeList.size() == 0) {
            throw new SystemException(SystemException.NOT_ALLOW_DELETE).setBusinessMessage("没有可删除的数据");
        }
        int successNum = 0;
        for (SysPostUnique sysPostKey : sysPostCodeList) {
            successNum += this.deletePost(sysPostKey);
        }
        return successNum;
    }

    /**
     * 新增保存岗位信息
     *
     * @param post 岗位信息
     * @return 结果
     */
    @Override
    @Transactional
    public int insertPost(SysPost post) {

        if (UserConstants.NOT_UNIQUE.equals(this.checkPostNameUnique(post.getPostId(), post.getDeptId(), post.getPostName()))) {
            throw new SystemException(SystemException.NOT_ALLOW_INSERT).setBusinessMessage("新增岗位'" + post.getPostName() + "'失败，岗位名称已存在");
        } else if (UserConstants.NOT_UNIQUE.equals(this.checkPostCodeUnique(post.getPostId(), post.getDeptId(), post.getPostCode()))) {
            throw new SystemException(SystemException.NOT_ALLOW_INSERT).setBusinessMessage("新增岗位'" + post.getPostName() + "'失败，岗位权限已存在");
        }

        int successNum = 0;
        //当存在的时候
        SysPost sysPostOrigin = postMapper.selectPostByDeptAndCodeOrg(post.getDeptId(), post.getPostCode());
        if (sysPostOrigin != null && "2".equals(sysPostOrigin.getDelFlag())) {
            SysPost postUpdate = new SysPost();
            postUpdate.setPostId(sysPostOrigin.getPostId());
            postUpdate.setDelFlag("0");
            postMapper.updatePost(postUpdate);
            successNum = this.updatePost(post);
        } else {
            // 新增岗位信息
            successNum = postMapper.insertPost(post);
        }

        return successNum;
    }

    /**
     * 修改保存岗位信息
     *
     * @param post 岗位信息
     * @return 结果
     */
    @Override
    public int updatePost(SysPost post) {

        if (post.getPostId() == null) {
            SysPost SysPostTemp = selectPost(post.getDeptId(), post.getPostCode());
            post.setPostId(SysPostTemp.getPostId());
        }

        SysPost sysPostOrigin = postMapper.selectPostById(post.getPostId());
        SysPost postOld = this.selectPost(post.getDeptId(), sysPostOrigin.getPostCode());


        //判断是否为顶层
        if (!postOld.getIsTopFloor().equals("Y")) {
            if (post.getPostCode() != null && !post.getPostCode().equals(postOld.getPostCode())) {
                throw new SystemException(SystemException.NOT_ALLOW_UPDATE).setBusinessMessage("不是原始岗位不允许修改权限标识");
            }

            //不是原始的岗位 不允许修改是否继承
            if (post.getIsAllowExtends() != null && !postOld.getIsAllowExtends().equals(post.getIsAllowExtends())) {
                throw new SystemException(SystemException.NOT_ALLOW_UPDATE).setBusinessMessage("不是原始岗位不允许修改继承标识");
            }
        }

        if (post.getIsAllowExtends() != null) {
            if (postOld != null && postOld.getIsAllowExtends() != null && postOld.getIsAllowExtends().equals(post.getIsAllowExtends())) {
                post.setIsAllowExtends(null);
            } else if (post.getIsAllowExtends().equals("N")) {//当改为不允许继承的时候需要判断是否已经继承了
                if (getExtendPosts(postOld.getDeptId(), postOld.getPostCode()).size() > 0) {
                    if (post.getIsAllowExtends() != null && !postOld.getIsAllowExtends().equals(post.getIsAllowExtends())) {
                        throw new SystemException(SystemException.NOT_ALLOW_UPDATE).setBusinessMessage("该岗位存在继承，不允许修改继承标识");
                    }
                }
            }
        }

        if (UserConstants.NOT_UNIQUE.equals(this.checkPostNameUnique(post.getPostId(), post.getDeptId(), post.getPostName()))) {
            throw new SystemException(SystemException.NOT_ALLOW_UPDATE).setBusinessMessage("修改岗位'" + post.getPostName() + "'失败，岗位名称已存在");
        } else if (UserConstants.NOT_UNIQUE.equals(this.checkPostCodeUnique(post.getPostId(), post.getDeptId(), post.getPostCode()))) {
            throw new SystemException(SystemException.NOT_ALLOW_UPDATE).setBusinessMessage("修改岗位'" + post.getPostName() + "'失败，岗位已存在");
        }

        //当已经删除
        if (sysPostOrigin != null) {
            if (sysPostOrigin.getDelFlag().equals("2")) {
                BeanUtils.copyPropertiesIgnoreNull(sysPostOrigin, postOld);
                post.setDelFlag("0");//启用
            }
        }


        //如果是顶层修改权限标识 要校验底层是否已经引用过
        if (!postOld.getPostCode().equals(post.getPostCode())) {
            //批量修改子的  这里存在一个问题如果子部门存在需要修改的部门的话会出现重复的 先人为控制 待以后再优化
            this.batchUpdatePostCode(postOld.getDeptId(), postOld.getPostCode(), post.getPostCode());
            //还需要修改sys_post_dept sys_post_menu
        }

        //当新的和老的没有变化的时候不需要替换

        if (postOld.getPostName() != null && postOld.getPostName().equals(post.getPostName())) {
            post.setPostName(null);
        }

        if (postOld.getPostSort() != null && postOld.getPostSort().equals(post.getPostSort())) {
            post.setPostSort(null);
        }

        if (postOld.getStatus() != null && postOld.getStatus().equals(post.getStatus())) {
            post.setStatus(null);
        }

        if (postOld.getRemark() != null && postOld.getRemark().equals(post.getRemark())) {
            post.setRemark(null);
        }

        if (postOld.getDelFlag() != null && postOld.getDelFlag().equals(post.getDelFlag())) {
            post.setDelFlag(null);
        }

        if (postOld.getIsAllowExtends() != null && postOld.getIsAllowExtends().equals(post.getIsAllowExtends())) {
            post.setIsAllowExtends(null);
        }


        boolean isEditData = false;//是否有修改数据
        if (post.getPostName() != null || post.getPostSort() != null
                || post.getStatus() != null
                || post.getDelFlag() != null || post.getIsAllowExtends() != null
                || post.getRemark() != null) {
            isEditData = true;
        }
        post.setUpdateTime(DateUtils.getNowDate());
        post.setUpdateBy(SecurityUtils.getUsername());
        int successNum = 0;
        if (!postOld.getDeptId().equals(post.getDeptId()) && isEditData) {
            post.setPostId(null);
            if (post.getIsAllowExtends() == null) {
                post.setIsAllowExtends("Y");
            }
            successNum = postMapper.insertPost(post);
//            throw new SystemException(SystemException.NOT_ALLOW_UPDATE).setBusinessMessage("不允许修改部门");
            //当部门不同的时候证明这个部门没有 需要添加
        } else {
            // 修改岗位信息
            successNum = postMapper.updatePost(post);
        }

        return successNum;
    }

    @Override
    @Transactional
    public int batchUpdatePostCode(Long deptId, String postOldCode, String postNewCode) {
        return postMapper.batchUpdatePostCode(deptId, postOldCode, postNewCode);
    }

    @Override
    public SysPost selectPostByDeptAndCode(Long deptId, String postCode) {
        SysPostParams sysPostParams = new SysPostParams();
        sysPostParams.setPostCode(postCode);
        sysPostParams.setDeptId(deptId);
        Page<SysPost> page = new Page<>(1, -1);
        List<SysPost> sysPosts = this.selectPostList(page,sysPostParams).getRecords();
        if (sysPosts != null && sysPosts.size() > 0) {
            return sysPosts.get(0);
        } else {
            return null;
        }

    }

    @Override
    public SysPost selectExtendPostByDeptAndCode(Long deptId, String postCode) {
        SysPost sysPost = this.selectPostByDeptAndCode(deptId, postCode);
        if (sysPost != null) {
            return sysPost;
        } else {
            SysDept sysDept = sysDeptService.selectDeptById(deptId);
            if (sysDept == null || sysDept.getParentId() == 0) {
                return null;
            }
            return selectExtendPostByDeptAndCode(sysDept.getParentId(), postCode);
        }
    }
}
